<?php

namespace App\Services\Account;

use App\Models\User;
use Brick\Math\BigDecimal;
use Brick\Math\RoundingMode;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Relations\HasMany;

abstract class AccountAbstract
{
    protected User $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    protected function record(BigDecimal $money, $remark, $reason, $data = [])
    {
        DB::transaction(function () use ($money, $remark, $reason, $data) {

            /**
             * @var User $user
             */
            $user = User::lockForUpdate()->find($this->user->id);

            $field = $this->account()->getModel()->getTable();

            
            $origin = $user->{$field};

            if($field == "apples"){

                 $money = $money->toScale(8, RoundingMode::HALF_UP);
            }else{

                 $money = $money->toScale(2, RoundingMode::HALF_UP);
            }
            
            $userMoneyWillBe = big_decimal($user->{$field})->plus($money);

            $fromUserId = 0;

            if($remark == 'gold_record_direct_prize' or $remark == 'gold_record_team_prize'){
                $fromUserId = $data['from_user_id'];
            }

            $childrenId = 0;

            if($remark == 'first_level' or $remark == 'second_level'){
                $childrenId = $data['children_id'];
            }

            $job = "";
             if($remark == 'company_transfer_balances'){
                $job = $data['job'];
            }


            $orderId = 0;

            if($remark == 'first_level' or $remark == 'second_level' or $remark=="own_order"){
                $orderId = $data['order_id'];
            }

            $this->account()->create([
                'origin' => $origin,
                'result' => (string)$userMoneyWillBe,
                'money' => (string)$money,
                'remark' => $remark,
                'reason' => $reason,
                'data' => $data,
                'from_user_id' => $fromUserId,
                'children_id'=>$childrenId,
                'company_job' => $job,
                'order_id'=>$orderId,
            ]);

            if (($remark == 'resold_profit_coins'
                or $remark == 'gold_record_direct_prize'
                or $remark == 'gold_record_team_prize')
                and $money->isGreaterThan(0)) {

                $allDividendCoins = $money->plus($user->dividend_all);
                $dayDividendCoins = $money->plus($user->dividend_day);

                $user->refresh()->update([
                    $field => (string)$userMoneyWillBe,
                    'dividend_all' => $allDividendCoins,
                    'dividend_day' => $dayDividendCoins,
                ]);
            } else {
                $user->update([$field => (string)$userMoneyWillBe]);
            }
        });
    }

    abstract protected function account(): HasMany;
}
